using AutoMapper;
using DeZhen.CollaborationPlatform.IRepository.ApiCallLog;
using DeZhen.CollaborationPlatform.IService.ApiCallLog;
using DeZhen.CollaborationPlatform.Model.Common;
using DeZhen.CollaborationPlatform.Model.DTO.ApiCallLog;
using DeZhen.CollaborationPlatform.Model.Entities;
using SqlSugar;
using Yitter.IdGenerator;

namespace DeZhen.CollaborationPlatform.Service.ApiCallLog
{
    /// <summary>
    /// 接口调用日志服务实现
    /// </summary>
    public class ApiCallLogService : IApiCallLogService
    {
        private readonly IApiCallLogRepository _repository;
        private readonly IMapper _mapper;

        public ApiCallLogService(IApiCallLogRepository repository, IMapper mapper)
        {
            _repository = repository;
            _mapper = mapper;
        }

        /// <inheritdoc />
        public async Task<PageResult<ApiCallLogDTO>> GetListToPageAsync(QueryApiCallLogPage param)
        {
            var query = (await _repository.GetListAsync())
                .WhereIF(param.ApiId.HasValue, x => x.ApiId == param.ApiId)
                .WhereIF(!string.IsNullOrEmpty(param.ApiUrl), x => x.ApiUrl.Contains(param.ApiUrl))
                .WhereIF(!string.IsNullOrEmpty(param.ApiMethod), x => x.ApiMethod == param.ApiMethod)
                .WhereIF(!string.IsNullOrEmpty(param.ClientIp), x => x.ClientIp == param.ClientIp)
                .WhereIF(!string.IsNullOrEmpty(param.UserId), x => x.UserId == param.UserId)
                .WhereIF(param.ResponseCode.HasValue, x => x.ResponseCode == param.ResponseCode)
                .WhereIF(param.Status.HasValue, x => x.Status == param.Status)
                .WhereIF(param.RequestTimeStart.HasValue, x => x.RequestTime >= param.RequestTimeStart)
                .WhereIF(param.RequestTimeEnd.HasValue, x => x.RequestTime <= param.RequestTimeEnd)
                .OrderByDescending(x => x.RequestTime);

            var total = query.Count();
            var items = query.Skip((param.Page - 1) * param.PageSize).Take(param.PageSize).ToList();
            var result = _mapper.Map<List<ApiCallLogDTO>>(items);
            return new PageResult<ApiCallLogDTO> { TotalCount = total, Items = result };
        }

        /// <inheritdoc />
        public async Task<List<ApiCallLogDTO>> GetListAsync(QueryApiCallLog param)
        {
            var query = (await _repository.GetListAsync())
                .WhereIF(param.ApiId.HasValue, x => x.ApiId == param.ApiId)
                .WhereIF(!string.IsNullOrEmpty(param.ApiUrl), x => x.ApiUrl.Contains(param.ApiUrl))
                .WhereIF(!string.IsNullOrEmpty(param.ApiMethod), x => x.ApiMethod == param.ApiMethod)
                .WhereIF(!string.IsNullOrEmpty(param.ClientIp), x => x.ClientIp == param.ClientIp)
                .WhereIF(!string.IsNullOrEmpty(param.UserId), x => x.UserId == param.UserId)
                .WhereIF(param.ResponseCode.HasValue, x => x.ResponseCode == param.ResponseCode)
                .WhereIF(param.Status.HasValue, x => x.Status == param.Status)
                .WhereIF(param.RequestTimeStart.HasValue, x => x.RequestTime >= param.RequestTimeStart)
                .WhereIF(param.RequestTimeEnd.HasValue, x => x.RequestTime <= param.RequestTimeEnd)
                .OrderByDescending(x => x.RequestTime)
                .ToList();
            return _mapper.Map<List<ApiCallLogDTO>>(query);
        }

        /// <inheritdoc />
        public async Task<ApiCallLogDTO> GetByIdAsync(long id)
        {
            var model = await _repository.GetByIdAsync(id);
            if (model == null)
                throw new Exception("接口调用日志不存在");
            return _mapper.Map<ApiCallLogDTO>(model);
        }

        /// <inheritdoc />
        public async Task<long> AddAsync(ApiCallLogAdd input)
        {
            var model = _mapper.Map<ApiCallLogAdd, ApiCallLogs>(input);

            model.Id = YitIdHelper.NextId();
            model.CreateTime = DateTime.Now;

            await _repository.CreateAsync(model);

            return model.Id;
        }

        /// <inheritdoc />
        public async Task<bool> UpdateAsync(ApiCallLogEdit input)
        {
            var model = await _repository.GetByIdAsync(input.Id);
            if (model == null)
                throw new Exception("接口调用日志不存在");

            var result = _mapper.Map(input, model);
            result.UpdateTime = DateTime.Now;

            return await _repository.UpdateAsync(result);
        }

        /// <inheritdoc />
        public async Task DeleteAsync(long id)
        {
            var model = await _repository.GetByIdAsync(id);
            if (model == null)
                throw new Exception("接口调用日志不存在");

            await _repository.DeleteAsync(id);
        }
    }
}